#include "Player.h"
#include "Prop.h"
#include "monster.h"
#include <stdio.h>
#include <stdlib.h>
#include <DynamicArray.h>


void InitPlayer(player *p)
{
    p->hp = 60;
    p->attack = 5 ;
    p->def = 1;
    p->x = 0;
    p->y = 0;
    sscanf(" 🤡 ","%s",p->symbol);
    p->exp = 0;
    p->level = 0;
    p->golden = 20;
    p->crit = 0;
    p->parry = 0;
    p->sp = 0;
    p->w = NULL;
    p->d = NULL;

    InitDynamicArray(&p->bag);

}

void PlayerMove(player *p ,DArray *ms,char* (*map)[MAPSIZE])
{
    //将原来的位置清空
    map[p->x][p->y] = "     ▫ "; 

    char choice = 0;
    printf("请选择玩家|%2s| 🤡 移动方向(⬆(w), ⬅ (a), ⬇(s), ➡ (d), 进入商店🛒(p), 打开背包💼(b), 打开菜单栏🔆(m):\n",p->name.string);
    scanf(" %c",&choice);
    while(getchar() != '\n');

    switch(choice)
    {
        case 'w':
                p->x--;
                if(p->x < 0)
                    p->x = 0;
                break;
        case 's':
                p->x++;
                if(p->x >= MAPSIZE)
                    p->x = MAPSIZE-1;
                break;
        case 'a':
                p->y--;
                if(p->y < 0)
                    p->y = 0;
                break;
        case 'd':
                p->y++;
                if(p->y >= MAPSIZE)
                    p->y = MAPSIZE-1;
                break;
        case 'p':       
                printf("\n");
                printf("你已选择前往商店🛒,正在前往中。。。。。。\n");      
                ShopInterFace(p);
                break;
        case 'b':
                printf("\n");
                printf("你已选择前往背包💼,正在前往中。。。。。。\n");  
                ShowBag(p);
                break;
        case 'm':
                printf("\n");
                printf("你已选择打开菜单栏💻，正在前往中。。。。。。\n");
                MenuInterFace(p,ms,map);
                break;
        default:break;
    }

    //附上新位置
    map[p->x][p->y] = p->symbol;
}

void MenuInterFace(player *p,DArray *ms,char* (*map)[MAPSIZE])
{
    sleep(1);
    while(1)
    {
        system("clear");
        printf("\n\n\n");
        printf("这是你的菜单栏界面💻 \n");
        printf("🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳✨✨🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("\n请做出你的选择  \n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳  1、存储数据            🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳  2、读取数据            🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳  3、保存并退出游戏      🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳  4、返回游戏            🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("\n🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳✨✨🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        int choice = 0;
        scanf("%d",&choice);
        while (getchar() != '\n');
        switch(choice)
        {
            case 1:
            printf("正在前往存档点，请稍后。。。。。。\n");
            sleep(1);
            SaveFileInterFace(p,ms,map);
            return;

            case 2:
            printf("正在前往存档点，请稍后。。。。。。\n");
            sleep(1);
            LoadFileInterFace(p,ms,map);
            return;

            case 3:
            printf("你已选择退出游戏！游戏将自动保存到存档 !\n");
            printf("正在为你存档中。。。。。。\n");
            MyStr s1 = PlayerToString(p);
            WriteToFIle("/home/lvguanzhong/1class/MyMagicTower/SaveData/AutoSaveFile.txt",s1.string,s1.len);
            MyStr s2 = MonstersToString(ms);
            AppendToFIle("/home/lvguanzhong/1class/MyMagicTower/SaveData/AutoSaveFile.txt",s2.string,s2.len);
            sleep(1);
            printf("存档成功！\n");
            sleep(1);
            printf("魔塔游戏期待着你的再次光临！\n");
            sleep(1);
            exit(0);
        
            case 4:
            printf("你已选择返回游戏！\n");
            sleep(1);
            return;
        }
    }
 
}

void SaveFileInterFace(player *p,DArray *ms,char* (*map)[MAPSIZE])
{
    sleep(1);
    while(1)
    {
        system("clear");
        printf("\n\n\n");
        printf("这是你的存档界面🔆\n");
        printf("🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳✨✨🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("\n请做出你的选择  \n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳  1、存档 1      🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳 \n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳  2、存档 2      🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳  3、存档 3      🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("\n🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳✨✨🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("                \n                                       请按q键返回游戏\n");
        char choice = 0;
        scanf(" %c",&choice);
        while(getchar() != '\n');
        switch(choice)
        {
            case '1':
                    printf("已经为你打开存档 1, 正在为你存档中。。。。。。\n");
                    char file1[255] = {0};
                    sprintf(file1,"/home/lvguanzhong/1class/MyMagicTower/UserAccount/%s-SaveFile1.txt",p->name.string);
                    MyStr str1 = PlayerToString(p);
                    WriteToFIle(file1,str1.string,str1.len);
                    MyStr mstr1 = MonstersToString(ms);    
                    AppendToFIle(file1,mstr1.string,mstr1.len);
                    sleep(1);
                    printf("存档成功！\n");
                    sleep(1);
                    break;

            case '2':
                    printf("已经为你打开存档 2, 正在为你存档中。。。。。。\n");
                    char file2[255] = {0};
                    sprintf(file2,"/home/lvguanzhong/1class/MyMagicTower/UserAccount/%s-SaveFile2.txt",p->name.string);
                    MyStr str2 = PlayerToString(p);
                    WriteToFIle(file2,str2.string,str2.len);
                    MyStr mstr2 = MonstersToString(ms);
                    AppendToFIle(file2,mstr2.string,mstr2.len); 
                    sleep(1);
                    printf("存档成功！\n");
                    sleep(1);
                    break;
            case '3':
                    printf("已经为你打开存档 3, 正在为你存档中。。。。。。\n");
                    char file3[255] = {0};
                    sprintf(file3,"/home/lvguanzhong/1class/MyMagicTower/UserAccount/%s-SaveFile3.txt",p->name.string);
                    MyStr str3 = PlayerToString(p);
                    WriteToFIle(file3,str3.string,str3.len);
                    MyStr mstr3 = MonstersToString(ms);
                    AppendToFIle(file3,mstr3.string,mstr3.len);
                    sleep(1);
                    printf("存档成功！\n");
                    sleep(1);
                    break;
            case 'q':
                    printf("正在退出中，请稍候。。。。。。\n");
                    sleep(1);
                    return;
        }
    }

   
}

void LoadProgram(player *p,DArray *ms,MyStrList* content)
{
    //初始化人物数据，方便读档没有垃圾值
    InitPlayer(p);
    //清除原有怪物列表
    InitDynamicArray(ms);
    //读取人物信息
    ResizeString(&p->name,20);
    sscanf(content->stringList[0].string,"%s %d %d %d %d %d %d %d %d %d %d %d",p->symbol,&p->x,&p->y,&p->level,&p->exp,&p->sp,&p->hp,&p->attack,&p->def,&p->crit,&p->parry,&p->golden);

    //读取人物装备的武器和防具
    if(content->stringList[1].len == 1)
        p->w = NULL;
    else
    {
        //新建一个武器指针承接文件读取出的数据
        weapon *w = CreateWeapon(" ",0,0,0);
        ResizeString(&w->name,40);
        sscanf(content->stringList[1].string,"%s %d %d %d",w->name.string,&w->attack,&w->crit,(int*)&w->effect);
        p->w = w;
    }    
    if(content->stringList[2].len == 1)
        p->d = NULL;
    else
    {
        //新建一个防具指针承接文件读取出的数据
        defence *d = CreateDefence(" ",0,0,0);
        ResizeString(&d->name,40);
        sscanf(content->stringList[2].string,"%s %d %d %d\n",d->name.string,&d->def,&d->parry,(int*)&d->effect);
        p->d = d;
    }
        
    //读取背包中的道具
    int i = 3;
    for(;content->stringList[i].len != 1 ; i++)
    {
        int hp = 0,atk = 0,def = 0,crit = 0,parry = 0,effect = -1;
        char name[30] = {0};
        enum PropType type;
        int cmp = content->stringList[i].string[0] - 48;
        if(cmp == Weapon)
        {
            sscanf(content->stringList[i].string,"%d %s %d %d %d",(int*)&type,name,&atk,&crit,&effect);
            p->bag.InsertArrayTail(&p->bag,CreateProp(Weapon,CreateWeapon(name,atk,crit,effect)));
        }
        else if(cmp == Defence)
        {
            sscanf(content->stringList[i].string,"%d %s %d %d %d",(int*)&type,name,&def,&parry,&effect);
            p->bag.InsertArrayTail(&p->bag,CreateProp(Defence,CreateDefence(name,def,parry,effect)));            
        }
        else if(cmp == Medicament)
        {
            sscanf(content->stringList[i].string,"%d %s %d %d %d %d %d %d",(int*)&type,name,&hp,&atk,&def,&crit,&parry,&effect);
            p->bag.InsertArrayTail(&p->bag,CreateProp(Medicament,CreateMedicament(name,hp,atk,def,crit,parry,effect)));              
        }
    }
    i++;

    for(; content->stringList[i].len != 1; i++)
    {
        monster *m = CreateMonsterLoad(0,0," ",0,0,0," ",0,0);
        ResizeString(&m->name,40);
        char symbol[20] = {0};
        sscanf(content->stringList[i].string,"%s %s %d %d %d %d %d %d %d",symbol,m->name.string,&m->x,&m->y,&m->hp,&m->attack,&m->def,&m->exp,&m->golden);
        ms->InsertArrayTail(ms,CreateMonsterLoad(m->x,m->y,m->name.string,m->hp,m->attack,m->def,symbol,m->exp,m->golden));
        ClearString(&m->name);
    }
}

void LoadFileInterFace(player *p,DArray *ms,char* (*map)[MAPSIZE])
{
    sleep(1);
    while(1)
    {
        system("clear");
        printf("\n\n\n");
        printf("这是你的读档栏界面🆔\n");
        printf("🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳✨✨🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("\n请做出你的选择  \n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳  1、读取存档 1      🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳 \n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳  2、读取存档 2      🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳  3、读取存档 3      🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳  4、读取自动存档      🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf(" 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("\n🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳✨✨🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("                \n                                          请按q键返回游戏\n");
        char choice = 0;
        scanf(" %c",&choice);
        while(getchar() != '\n');
        switch(choice)
        {
            case '1':

                    char file1[255] = {0};
                    sprintf(file1,"/home/lvguanzhong/1class/MyMagicTower/UserAccount/%s-SaveFile1.txt",p->name.string);
                    if(IsFileExist(file1) == false)
                    {
                        printf("你还没有存档在这,请返回选择其它存档或者开始新的冒险！\n");
                        sleep(1);
                        break;
                    }
                    printf("已经为你打开存档 1, 正在为你读档中。。。。。。\n");
                    MyStrList content1 = GetLineFromFile(file1);
                    LoadProgram(p,ms,&content1);
                    InitMap(map);
                    map[p->x][p->y] = p->symbol;
                    SetMonsterPosition(ms,map);

                    printf("读取存档成功！\n");
                    sleep(1);
                    break;

            case '2':
                    
                    char file2[255] = {0};
                    sprintf(file2,"/home/lvguanzhong/1class/MyMagicTower/UserAccount/%s-SaveFile2.txt",p->name.string);
                    if(IsFileExist(file2) == false)
                    {
                        printf("你还没有存档在这,请返回选择其它存档或者开始新的冒险！\n");
                        sleep(1);
                        break;
                    }
                    printf("已经为你打开存档 2, 正在为你读档中。。。。。。\n");
                    MyStrList content2 = GetLineFromFile(file2);
                    LoadProgram(p,ms,&content2);
                    InitMap(map);
                    map[p->x][p->y] = p->symbol;
                    SetMonsterPosition(ms,map);

                    printf("读取存档成功！\n");
                    sleep(1);
                    break;
            case '3':
   
                    char file3[255] = {0};
                    sprintf(file3,"/home/lvguanzhong/1class/MyMagicTower/UserAccount/%s-SaveFile3.txt",p->name.string);
                    if(IsFileExist(file3) == false)
                    {
                        printf("你还没有存档在这,请返回选择其它存档或者开始新的冒险！\n");
                        sleep(1);
                        break;
                    }
                    printf("已经为你打开存档 3, 正在为你读档中。。。。。。\n");         
                    MyStrList content3 = GetLineFromFile(file3);
                    
                    LoadProgram(p,ms,&content3);
                    InitMap(map);
                    map[p->x][p->y] = p->symbol;
                    SetMonsterPosition(ms,map);

                    printf("读取存档成功！\n");
                    sleep(1);
                    break;
            case '4': 
                    char file4[255] = {0};
                    sprintf(file4,"/home/lvguanzhong/1class/MyMagicTower/UserAccount/%s-AutoSaveFile.txt",p->name.string);
                    if(IsFileExist(file4) == false)
                    {
                        printf("你还没有存档在这,请返回选择其它存档或者开始新的冒险！\n");
                        sleep(1);
                        break;
                    }
                    printf("已经为你打开自动存档, 正在为你读档中。。。。。。\n");
            
                    MyStrList content4 = GetLineFromFile(file4);
                    LoadProgram(p,ms,&content4);
                    InitMap(map);
                    map[p->x][p->y] = p->symbol;
                    SetMonsterPosition(ms,map);

                    printf("读取存档成功！\n");
                    sleep(1);
                    break;
            case 'q':
                    printf("正在退出中，请稍候。。。。。。\n");
                    sleep(1);
                    return;
        }
    }
    
}


void PrintPlayer(player *p)
{
    printf("玩家|%2s| 🤡 当前状态:    等级🔰 :| %2d/10 |      经验🥇  :| %3d/%3d |  金钱💰   :| %3d |  怒气值💢 :| ",p->name.string,p->level,p->exp,(p->level+1) *25,p->golden);
    int i = p->sp;
    while(i > 0)
    {
        printf(" ✡ ");
        i--;
    }
    printf(" /  ✡  ✡  ✡  |\n");
    printf("                         血量🤍 :| %2d/60 |     攻击力⚔️  :| %3d |     防御力🛡️   :| %3d |  暴击率✨ :| %3d/100 |   格挡率💥 :| %3d/100 |\n",p->hp,p->attack,p->def,p->crit,p->parry);
    printf("\n");
    if(p->w != NULL)
        printf("武器⚔ :|%21s  |                攻击力⚔️  :|%3d|  暴击率✨ :|%3d|  特殊效果 :|%d|\n",p->w->name.string,p->w->attack,p->w->crit,p->w->effect);
    if(p->d != NULL)
        printf("防具🛡 :|%21s  |                 防御力🛡️ :|%3d|  格挡率💥 :|%3d|  特殊效果 :|%d|\n",p->d->name.string,p->d->def,p->d->parry,p->d->effect);
    printf("\n");
}


void LevelUp(player *p)
{
    while(p->exp >= (p->level+1) *25)
    {
        p->level++;
        p->exp -= p->level * 25 ;
        printf("恭喜升级🔰  ,你已升到%d级!\n",p->level);
        p->hp = 60;
        p->def += 2;
        p->attack += 3;
        p->crit += 5;
        p->parry += 5;
        sleep(1);
    }
    if(p->level >= 10)
        p->level = 10;
}

bool CheckNameContain(void *ptr1, void *ptr2)
{
    void * name = (void *) ptr1;
    weapon *w = (weapon *)ptr2;
    if(IsContains(&w->name,name) == true)
        return true;
    return false;
}

void ShopInterFace(player *p)
{
    sleep(1);
    while(1)
    {
        system("clear");
        printf("\n\n");
        printf("🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳 欢迎来到商店🛒! ψ(｀∇´)ψ 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("以下是你可以购买的商品！\n");
        printf("1、无坚不摧的剑🔪           (攻击力⚔️     +10)       (暴击率✨  +50)           : ￥20\n");
        printf("2、双剑 ⚔️                   (攻击力⚔️     +15)       (暴击率✨  +30)           : ￥20\n");
        printf("3、嗜血拳套🤜               (攻击力⚔️     +10)       (特殊效果🩸:60概率吸血)   : ￥25\n");
        printf("4、坚不可摧的盾🛡️            (防御力🛡     +10)       (格挡率💥  +50)           : ￥20\n");
        printf("5、荆棘甲💱                 (防御力🛡     + 7)       (特殊效果💱:60概率反伤)   : ￥25\n");
   
        printf("6、小血瓶💗                 (回复量🤍    + 5)                                 : ￥ 4\n");
        printf("7、大血瓶💕                 (回复量🤍    +10)                                 : ￥ 6\n");
        printf("8、暴击药水✨               (回复量🤍    + 0)       (暴击率✨ +10)            : ￥10\n");
        printf("9、格挡药水💥               (回复量🤍    + 0)       (格挡率💥 +10)            : ￥10\n");
        printf("\n");
        printf("🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳 以上为商品目录 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("\n");
        printf("                                                                            q:退出商店🛒\n");
        printf("                                                                        你当前拥有金币💰%d\n",p->golden);
        printf("请做出你的选择: \n");
  
        char choice = 0;
        scanf(" %c",&choice);
        while(getchar() != '\n');

        switch(choice)
        {
            case '1':
                if(p->golden < 20)
                {
                    printf("余额💰不足，购买武器⚔ 失败！\n");
                    sleep(1);
                    break;
                }
                printf("购买武器⚔ ~成功！\n");
                printf("武器⚔ |无坚不摧的剑🔪|已放入你的背包💼中!\n");
                p->bag.InsertArrayTail(&p->bag,CreateProp(Weapon,CreateWeapon("无坚不摧的剑🔪",10,50,-1)));
                p->golden -= 20;
                sleep(1);
                break;
            case '2':
                if(p->golden < 20)
                {
                    printf("余额💰不足，购买武器⚔ 失败！\n");
                    sleep(1);
                    break;
                }
                printf("购买武器⚔ ~成功！\n");
                printf("武器⚔ |双剑⚔️ |已放入你的背包💼中!\n");
                p->bag.InsertArrayTail(&p->bag,CreateProp(Weapon,CreateWeapon("双剑⚔️",15,30,-1)));
                p->golden -= 25;
                sleep(1);
                break;
            case '3':
                if(p->golden < 25)
                {
                    printf("余额💰不足，购买武器⚔ 失败！\n");
                    sleep(1);
                    break;
                }
                printf("购买武器⚔ ~成功！\n");
                printf("武器⚔ |嗜血拳套🤜 |已放入你的背包💼中!\n");
                p->bag.InsertArrayTail(&p->bag,CreateProp(Weapon,CreateWeapon("嗜血拳套🤜",10,0,SuckBlood)));
                p->golden -= 25;
                sleep(1);
                break;         
            case '4':
                if(p->golden < 20)
                {
                    printf("余额💰不足，购买防具🛡 失败！\n");
                    sleep(1);
                    break;
                }
                printf("购买防具🛡 ~成功！\n");
                printf("防具🛡 |坚不可摧的盾🛡️ |已放入你的背包💼中!\n");
                p->bag.InsertArrayTail(&p->bag,CreateProp(Defence,CreateWeapon("坚不可摧的盾🛡️",10,50,-1)));
                p->golden -= 20;
                sleep(1);
                break;     
            case '5':
                if(p->golden < 25)
                {
                    printf("余额💰不足，购买防具🛡 失败！\n");
                    sleep(1);
                    break;
                }
                printf("购买防具🛡 ~成功！\n");
                printf("防具🛡 |荆棘甲💱 |已放入你的背包💼中!\n");
                p->bag.InsertArrayTail(&p->bag,CreateProp(Defence,CreateWeapon("荆棘甲💱",7,0,Reflex)));
                p->golden -= 25;
                sleep(1);
                break;           
            case '6':
                if(p->golden < 4)
                {
                    printf("余额💰不足，购买失败！\n");
                    break;
                }
                printf("购买药剂⚗ ~成功！\n");
                printf("药剂⚗ |小血瓶💗|已放入你的背包💼中!\n");
                p->bag.InsertArrayTail(&p->bag,CreateProp(Medicament,CreateMedicament("小血瓶💗",5,0,0,0,0,-1)));
                p->golden -= 4;
                sleep(1);
                break;
            case '7':
                if(p->golden < 6)
                {
                    printf("余额💰不足，购买失败！\n");
                    break;
                }
                printf("购买药剂⚗ ~成功！\n");
                printf("药剂⚗ |大血瓶💕|已放入你的背包💼中!\n");
                p->bag.InsertArrayTail(&p->bag,CreateProp(Medicament,CreateMedicament("大血瓶💕",10,0,0,0,0,-1)));
                p->golden -= 6;
                sleep(1);
                break;
            case '8':
                if(p->golden < 10)
                {
                    printf("余额💰不足，购买失败！\n");
                    break;
                }
                printf("购买药剂⚗ ~成功！\n");
                printf("药剂⚗ |暴击药水✨|已放入你的背包💼中!\n");
                p->bag.InsertArrayTail(&p->bag,CreateProp(Medicament,CreateMedicament("暴击药水✨",0,0,0,10,0,-1)));
                p->golden -= 10;
                sleep(1);
                break;
            case '9':
                if(p->golden < 10)
                {
                    printf("余额💰不足，购买失败！\n");
                    break;
                }
                printf("购买药剂⚗ ~成功！\n");
                printf("药剂⚗ |格挡药水💥|已放入你的背包💼中!\n");
                p->bag.InsertArrayTail(&p->bag,CreateProp(Medicament,CreateMedicament("格挡药水💥",0,0,0,0,10,-1)));
                p->golden -= 10;
                sleep(1);
                break;
            case 'q':
                printf("你选择退出商店！欢迎下次光临！\n");
                sleep(1);
                return;
        }
    }
}

static int count = 0;
void ShowProp(void *ptr)
{
    count++;
    prop *p = (prop*)ptr;
    if(p->type == Weapon)
    {
        weapon *w = (weapon*)p->ptr;
        printf("%2d、 武器 ⚔ : 名字:|%20s  | 攻击力⚔️  :|%2d|  暴击率✨ :|%2d|  特殊效果 :|%d|\n",count,w->name.string,w->attack,w->crit,w->effect);
    }
    else if(p->type == Defence)
    {
        defence *d = (defence*)p->ptr;
        printf("%2d、 防具 🛡 : 名字:|%20s  | 防御力🛡️  :|%2d|  格挡率💥 :|%2d|  特殊效果 :|%d|\n",count,d->name.string,d->def,d->parry,d->effect);
    }
    else if(p->type == Medicament)
    {
        medicament *m = (medicament*)p->ptr;
        printf("%2d、 药剂 ⚗ : 名字:|%20s  | 回复量🤍 :|%2d|  暴击率✨ :|%2d|  格挡率💥 :|%2d|\n",count,m->name.string,m->hp,m->crit,m->parry);
    }
}

bool SortByPropType(void *ptr1,void *ptr2)
{
    prop *p1 = (prop *)ptr1;
    prop *p2 = (prop *)ptr2;
    if(p1->type > p2->type)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int GetInput()
{
    int choice = 0;
    scanf(" %d",&choice);
    while(getchar() != '\n');
    return choice;
}


void UseProp(player *p,int index)
{
    if(index < 0 || index > p->bag.len)
    {
        printf("输入非法!  请重新输入！\n");
        return;
    }

    //第n个道具的指针
    prop *pro = p->bag.dp[index-1];
    if(pro->type == Weapon)
    {
        weapon *w = (weapon*)pro->ptr;
        printf("你是否要装备武器 ⚔ : 名字:|%20s  | 攻击力⚔️  :|%2d|  暴击率✨ :|%2d|  特殊效果 :|%d|\n",w->name.string,w->attack,w->crit,w->effect);
        printf("1、是   2、否\n");
        int choice = GetInput();
        if(choice == 1)
        {
            if(p->w == NULL)
            {
                printf("装备成功!\n");
                sleep(1);

                p->w = w;
                p->attack += p->w->attack;
                p->crit += p->w->crit;
                p->bag.RemoveByIndex(&p->bag,index-1,NULL);
                //释放道具
                free(pro);
            }
            else
            {
                printf("你已装备武器|%20s  |,请确认是否替换成|%s|: (1、是   2、否)\n",p->w->name.string,w->name.string);
                int choose = GetInput();
                if(choose == 1)
                {
                    p->bag.InsertArrayTail(&p->bag,CreateProp(Weapon,p->w));
                    printf("你已卸下武器|%20s  |,装备上新武器|%s|\n",p->w->name.string,w->name.string);
                    p->attack -= p->w->attack;
                    p->crit -= p->w->crit;
                    sleep(1);

                    p->w = w;
                    p->attack += p->w->attack;
                    p->crit += p->w->crit;
                    p->bag.RemoveByIndex(&p->bag,index-1,NULL);
                    //释放道具
                    free(pro);
                }
                else
                    return;
            }
        }
        else
            return;
    }
    else if(pro->type == Defence)
    {
        defence *d = (defence*)pro->ptr;
        printf("你是否要装备防具 🛡 : 名字:|%20s  | 防御力🛡️  :|%2d|  格挡率💥 :|%2d|  特殊效果 :|%d|\n",d->name.string,d->def,d->parry,d->effect);
        printf("1、是   2、否\n");
        int choice = GetInput();
        if(choice == 1)
        {
            if(p->d == NULL)
            {
                printf("装备成功!\n");
                sleep(1);

                p->d = d;
                p->def += p->d->def;
                p->parry += p->d->parry;
                p->bag.RemoveByIndex(&p->bag,index-1,NULL);
                //释放道具
                free(pro);
            }
            else
            {
                printf("你已装备防具|%20s  |,请确认是否替换成|%s|: (1、是   2、否)\n",p->d->name.string,d->name.string);
                int choose = GetInput();
                if(choose == 1)
                    {
                        p->bag.InsertArrayTail(&p->bag,CreateProp(Defence,p->d));
                        printf("你已卸下防具🛡 |%20s  |,装备上新防具|%20s  |\n",p->d->name.string,d->name.string);
                        p->def -= p->d->def;
                        p->parry -= p->d->parry;
                        sleep(1);

                        p->d = d;
                        p->def += p->d->def;
                        p->parry += p->d->parry;
                        p->bag.RemoveByIndex(&p->bag,index-1,NULL);
                        //释放道具
                        free(pro);
                    }
                else
                    return;

            }

        }
        else
            return;
    }
    else if(pro->type == Medicament)
    {
        medicament *m = (medicament*)pro->ptr;
        printf("你是否要使用药剂 ⚗ : 名字:|%20s|  回复量🤍 :|%2d|  \n",m->name.string,m->hp);
        printf("1、是   2、否\n");
        int choice = GetInput();
        if(choice == 1)
        {
            if(p->hp + m->hp <= 60)
            {
                printf("使用药剂 ⚗ |%20s  |成功!\n",m->name.string);
                p->hp += m->hp; 
                p->crit += m->crit;
                p->parry += m->parry;
            }      
            else
            {
                printf("使用药剂 ⚗ |%s|后会有部分浪费,请再确认是否使用:(1、是   2、否)\n",m->name.string);
                int choose = GetInput();
                if(choose == 1)
                    {
                        p->hp = 60;
                        if(p->crit + m->crit >=100)
                            p->crit = 100;
                        else
                            p->crit += m->crit;
                        if(p->parry + m->parry >=100)
                            p->parry = 100;
                        else
                            p->parry += m->parry;
                    }
                else
                    return;
            }
            p->bag.RemoveByIndex(&p->bag,index-1,NULL);
            //释放道具
            free(pro);
        }
        else
            return;
    }
}

void ShowBag(player *p)
{
    while(1)
    {
        sleep(1);
        p->bag.Sort(&p->bag,SortByPropType);
        system("clear");
        printf("\n\n");
        printf("🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳 这是你的背包💼界面 🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("\n");
        printf("以下是你拥有的物品:\n");
        count = 0;
        p->bag.DisplayDynamicArray(&p->bag,ShowProp);
        count = 0;
        if(p->bag.len == 0)
        {
            printf("\n");
            printf("抱歉！你还没有物品！\n");
        }       
        printf("\n");
        printf("🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳🏳\n");
        printf("\n");
        printf("                                                                                               q:退出背包💼\n");

        printf("这是你当前的状态：\n");
        PrintPlayer(p);
        printf("\n");
        if(p->bag.len != 0)
            printf("请选择道具前的编号进行操作：\n");
        char choice[10] = {0};
        scanf("%s",choice);
        while(getchar() != '\n');
        if(strcmp(choice,"q") == 0)        
        {
            printf("\n");
            printf("你已选择关闭背包💼！\n");
            sleep(1);
            return;
        }
        else
            UseProp(p,atoi(choice));
    }
}

MyStr PlayerToString(player *p)
{
    char str[2048] = {0};

    sprintf(str,"%s %d %d %d %d %d %d %d %d %d %d %d \n",p->symbol,p->x,p->y,p->level,p->exp,p->sp,p->hp,p->attack,p->def,p->crit,p->parry,p->golden);
    if(p->w != NULL)
    {
        char wpn[100] = {0};
        sprintf(wpn," %s %d %d %d\n",p->w->name.string,p->w->attack,p->crit,p->w->effect);
        strcat(str,wpn);
    }
    else
        strcat(str,",\n");
    if(p->d != NULL)
    {
        char df[100] = {0};
        sprintf(df," %s %d %d %d\n",p->d->name.string,p->d->def,p->parry,p->d->effect);
        strcat(str,df);
    }
    else
        strcat(str,",\n");

    for(int i = 0; i < p->bag.len; i++)
    {
        char prp[100] = {0};
        prop *pro = p->bag.dp[i];
        if(pro->type == Weapon)
        {
            MyStr s = WeaponToString((weapon*)pro->ptr);
            strcat(str,s.string);
            ClearString(&s);
        }
        else if(pro->type == Defence)
        {
            MyStr s = DefenceToString((defence*)pro->ptr);
            strcat(str,s.string);
            ClearString(&s);
        }
        else if(pro->type == Medicament)
        {
            MyStr s = MedicamentToString((medicament*)pro->ptr);
            strcat(str,s.string);
            ClearString(&s);
        }
    }
    strcat(str,",\n");
    return GetString(str);
}
